<?php

namespace common\service;

use common\exception\LogicException;
use common\model\CosMediaModel;
use common\model\MessageTaskConfirmModel;
use common\model\NoteModel;
use common\model\UserModel;
use support\ErrorCode;
use support\SingletonTrait;
use common\model\GlobalNoticeModel;
use think\Hook;

class GlobalNoticeService
{

    use SingletonTrait;

    /**
     * 发布公告
     * @param int   $userId
     * @param array $data
     * @return array
     * @throws \Exception|\Throwable
     */
    public function publish(int $userId, array $data)
    {
        $noticeData = $data['global_notice'];
        $noticeAttachment = $data['global_notice_attachment'] ?? [];
        $joinUsers = (array)($noticeData['join_users'] ?: []);
        unset($noticeData['join_users']);

        $joinUserIds = [];
        if (!empty($joinUsers)) {
            $joinUsersIdRes = model(UserModel::class)->where(['union_id' => ['in', $joinUsers]])->column('id');
            $joinUserIds = array_unique($joinUsersIdRes);
        }

        // 公告全员通知 数组 设置 1、内部所有成员确认查收 2、外部所有成员确认查收
        if (isset($noticeData['notify_setting'])) {
            $noticeData['global_notice_notify_setting'] = $noticeData['notify_setting'];
            unset($noticeData['notify_setting']);
        }

        // 是否定时发布通知 1:是 0:否
//        if (isset($noticeData['plan_switch'])) {
//            $noticeData['global_notice_plan_switch'] = $noticeData['plan_switch'];
//            unset($noticeData['plan_switch']);
//        }

        // 定时发布通知的时间
//        if (isset($noticeData['plan_time'])) {
//            $noticeData['global_notice_plan_time'] = $noticeData['plan_time'];
//            unset($noticeData['plan_time']);
//        }

        // 接收方式 1:系统警告弹窗
        if (isset($noticeData['receive_way'])) {
            $noticeData['json']['global_notice_receive_way'] = $noticeData['receive_way'];
            unset($noticeData['receive_way']);
        }

        $noticeData['global_notice_join_count'] = count($joinUsers);
        $globalNoticeModuleId = module_by_code('global_notice')['id'];

        $globalNoticeModel = model(GlobalNoticeModel::class);
        $globalNoticeModel->startTrans();

        $hookData = [];
        try {
            $addData = query_array_construct([
                'type' => '',
                'title' => '',
                'summary' => '',
                'is_top' => '',
                'json' => ''
            ], $noticeData, [
                'json' => []
            ]);
            $hookData['notice_data'] = $addData;
            $hookData['notice_data']['created_by'] = $userId;
            $hookData['notice_data']['join_users'] = $joinUserIds;

            $globalNoticeRes = model(GlobalNoticeModel::class)->addItem($addData);

            // 公告正文
            $noteAddData = [
                'note' => [
                    'type' => 'text',
                    'module_id' => $globalNoticeModuleId,
                    'link_id' => $globalNoticeRes['id'],
                    'demand_type' => 'default',
                    'text' => $noticeData['content']
                ],
            ];
            if (!empty($noticeAttachment)) {
                $noteAddData['note_cos_media'] = $noticeAttachment;
            }
            $noteRes = NoteService::getInstance()->createNote($noteAddData);

            $saveDataTemplate = [
                'link_id' => $globalNoticeRes['id'],
                'link_module_code' => 'global_notice',
                'confirm' => 'default',
                'link_step_category' => '',
                'source_type' => 'global_notice_confirm',
                'remark' => '',
                'project_id' => 0,
                'tenant_id' => \request()->getTenantId(),
                'created_by' => $userId,
                'created' => time(),
            ];
            $saveData = [];
            foreach ($joinUserIds as $joinUserId) {
                $saveData[] = array_replace($saveDataTemplate, ['confirm_user_id' => $joinUserId]);
            }
            model(MessageTaskConfirmModel::class)->addAll($saveData);

            $globalNoticeModel->commit();
        } catch (\Throwable $e) {
            $globalNoticeModel->rollback();
            APP_DEBUG && trace(format_exception_info($e), 'ERR');
            throw $e;
        }
        $data['global_notice']['id'] = $globalNoticeRes['id'];
        $hookData['notice_id'] = $globalNoticeRes['id'];
        $hookData = [
            'type' => 'global_notice_publish',
            'data' => $hookData
        ];
        Hook::listen('global_notice_publish_after', $hookData);
        return $data;
    }

    /**
     * 发布全局公告评论
     * @param int   $userId
     * @param array $data
     * @return array
     * @throws \Exception|\Throwable
     */
    public function comment(int $userId, array $data)
    {
        $commentData = $data['comment'];
        $mentionedUsers = $data['mentioned_users'] ?? '';
        $noticeId = (int)$commentData['notice_id'] ?? 0;
        $noticeData = model(GlobalNoticeModel::class)->find($noticeId);

        if (!empty($mentionedUsers)) {
            $mentionUsersIdRes = model(UserModel::class)
                ->field('id')
                ->where(['union_id' => ['in', explode(',', $mentionedUsers)]])
                ->select();
            $mentionUserIds = $mentionUsersIdRes ? array_column($mentionUsersIdRes, 'id') : [];
        } else {
            $mentionUserIds = [];
        }

        if (empty($noticeData)) {
            throw new LogicException('global notice data not exists', ErrorCode::GLOBAL_NOTICE_NOT_EXISTS);
        }
        $noticeCommentNoteModel = model(NoteModel::class);
        $noticeCommentNoteModel->startTrans();

        try {
            $noteCommentAddData = [
                'comment_subject_id' => $commentData['pid'] ?? 0,// 评论父级id
                'demand_type' => 'comment',
                'link_id' => $noticeId, // 关联全局公告id
                'module_id' => module_by_code('global_notice')['id'],
                'type' => 'text',
                'text' => $commentData['content'],
            ];
            $noticeCommentNoteRes = model(NoteModel::class)->addItem($noteCommentAddData);

            if (!empty($mentionUserIds)) {
                $saveDataTemplate = [
                    'link_id' => $noticeData['id'],
                    'link_module_code' => 'global_notice',
                    'confirm' => 'default',
                    'link_step_category' => '',
                    'source_type' => 'global_notice_at',
                    'remark' => '',
                    'project_id' => 0,
                    'tenant_id' => \request()->getTenantId(),
                    'created_by' => $userId,
                    'created' => time(),
                ];
                $saveData = [];
                foreach ($mentionUserIds as $mentionUserId) {
                    $saveDataItem = array_replace($saveDataTemplate, ['confirm_user_id' => $mentionUserId]);
                    if ($mentionUserId == $userId) {
                        $saveDataItem['confirm'] = 'yes';
                    }
                    $saveData[] = $saveDataItem;
                }
                model(MessageTaskConfirmModel::class)->addAll($saveData);
            }
            $noticeCommentNoteModel->commit();
        } catch (\Throwable $e) {
            $noticeCommentNoteModel->rollback();
            APP_DEBUG && trace(format_exception_info($e), 'ERR');
            throw $e;
        }
        $data['comment']['id'] = $noticeCommentNoteRes['id'];
        return $data;
    }

    /**
     * 全局公告统计
     * @param     $param
     * @param int $userId
     * @return array|false|mixed|string
     */
    public function getCount($param, int $userId)
    {
        $filter = $param['filter'] ?? [];
        if (isset($filter['global_notice.search_type'])) {
            $filter[] = $this->parseSearchTypeCondition($filter, $userId);
            if (isset($filter['global_notice.search_type'])) {
                unset($filter['global_notice.search_type']);
            }
        }
        $globalNoticeModuleId = module_by_code('global_notice')['id'];
        $res = model(GlobalNoticeModel::class)
            ->join("note ON note.module_id={$globalNoticeModuleId} AND note.link_id=global_notice.id AND note.type='text' AND demand_type = 'default'")
            ->join("user on global_notice.created_by = user.id", "left")
            ->join("message_task_confirm on message_task_confirm.link_module_code = 'global_notice' and message_task_confirm.link_id = global_notice.id", "left")
            ->field('count(distinct global_notice.id) as count')
            ->where($filter)
            ->select();
        return $res[0];
    }

    /**
     * 公告列表
     * @param     $param
     * @param int $userid
     * @return array|mixed|string
     * @throw \Throwable|\Exception
     */
    public function list($param, int $userId)
    {
        $page = $param['page'] ?? [1, C("database.database_max_select_rows")];
        $order = $param['order'] ?? "global_notice.id DESC";
        $filter = $param['filter'] ?? [];
        $fields = $param['fields'] ?? [];

        if (isset($filter['global_notice.search_type'])) {
            $filter[] = $this->parseSearchTypeCondition($filter, $userId);
            if (isset($filter['global_notice.search_type'])) {
                unset($filter['global_notice.search_type']);
            }
        }

        if (empty($fields)) {
            $fields = [
                "global_notice.id", "global_notice.type", "global_notice.title", "global_notice.summary", "global_notice.is_top",
                "global_notice.created as created_at",
                "global_notice.created_by as publisher",
                "user.name AS publish_user_name", "user.avatar AS publisher_user_avatar", "user.union_id AS publisher_union_id",
            ];
        }
        $globalNoticeQuery = model(GlobalNoticeModel::class);
        $globalNoticeModuleId = module_by_code('global_notice')['id'];
        $globalNoticeQuery = $globalNoticeQuery
            ->join("note ON note.module_id={$globalNoticeModuleId} AND note.link_id=global_notice.id AND note.type='text' AND demand_type = 'default'")
            ->join("user on global_notice.created_by = user.id", "left")
            ->join("message_task_confirm on message_task_confirm.link_module_code = 'global_notice' and message_task_confirm.link_id = global_notice.id", "left")
            ->field($fields)
            ->where($filter);

        if (isset($order)) {
            $globalNoticeQuery = $globalNoticeQuery->order($order);
        }

        $globalNoticeQuery = $globalNoticeQuery->group('global_notice.id');
        $globalNoticeQuery = $globalNoticeQuery->page($page[0], $page[1]);
        $globalNoticeRes = $globalNoticeQuery->select() ?: [];
        if ($fields == "global_notice.id") {
            return $globalNoticeRes;
        }

        $noticeCommentCountMap = [];
        $noticeIdList = array_column($globalNoticeRes, 'id');
        $noticeConfirmMap = [];
        if (!empty($noticeIdList)) {
            // 评论数量
            $noticeComment = model(NoteModel::class)
                ->where([
                    'link_id' => ['in', $noticeIdList],
                    'module_id' => module_by_code('global_notice')['id'],
                    'type' => 'text',
                    'demand_type' => 'comment',
                ])
                ->field('link_id, count(id) as count')
                ->group('link_id')
                ->select();
            $noticeCommentCountMap = array_column($noticeComment, 'count', 'link_id');

            // 确认map
            $confirmList = model(MessageTaskConfirmModel::class)
                ->where([
                    'link_id' => ['in', $noticeIdList],
                    'link_module_code' => 'global_notice',
                    'source_type' => ['in', [MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM, MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_AT]],
                ])
                ->field("link_id, confirm, confirm_user_id, source_type")
                ->select();
            foreach ($confirmList as $confirm) {
                switch ($confirm['source_type']) {
                    case MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM:
                        $confirmType = "confirm";
                        break;
                    default:
                    case MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_AT:
                        $confirmType = "at";
                }
                if (!isset($noticeConfirmMap[$confirm['link_id']][$confirmType])) {
                    $noticeConfirmMap[$confirm['link_id']][$confirmType] = [
                        'count_confirmed' => 0,
                        'count_not_confirmed' => 0,
                        'confirm_user_list' => [],
                        'not_confirm_user_list' => [],
                    ];
                }
                if ($confirm['confirm'] == 'yes') {
                    $noticeConfirmMap[$confirm['link_id']][$confirmType]['count_confirmed'] += 1;
                    $noticeConfirmMap[$confirm['link_id']][$confirmType]['confirm_user_list'][] = $confirm['confirm_user_id'];
                } else {
                    $noticeConfirmMap[$confirm['link_id']][$confirmType]['count_not_confirmed'] += 1;
                    $noticeConfirmMap[$confirm['link_id']][$confirmType]['not_confirm_user_list'][] = $confirm['confirm_user_id'];
                }
            }
        }

        $res = [];
        if (!empty($globalNoticeRes)) {
            foreach ($globalNoticeRes as $item) {
                $item['confirm_count'] = $noticeConfirmMap[$item['id']]['confirm']['count_confirmed'] ?? 0;          // 确认总数
                $item['total_join_count'] = ($noticeConfirmMap[$item['id']]['confirm']['count_confirmed'] ?? 0) + ($noticeConfirmMap[$item['id']]['confirm']['count_not_confirmed'] ?? 0); // 全部确认数
                $item['user_confirmed'] = in_array($userId, $noticeConfirmMap[$item['id']]['confirm']['confirm_user_list'] ?? []); // 是否确认
                $item['need_confirm'] = $item['user_confirmed'] || in_array($userId, $noticeConfirmMap[$item['id']]['confirm']['not_confirm_user_list'] ?? []); // 是否展示确认状态
                $item['comment_count'] = $noticeCommentCountMap[$item['id']] ?? 0;          // 评论总数
                $item['comment_confirmed'] = !in_array($userId, $noticeConfirmMap[$item['id']]['at']['not_confirm_user_list'] ?? []); // 是否当前用户确认了评论的at
                $res[] = $item;
            }
        }
        return $res;
    }

    /**
     * 获取公告内容
     * @param int   $globalNoticeId
     * @param array $fields
     * @return array|false|mixed|string
     */
    public function getContent(int $globalNoticeId, $fields = [])
    {
        if (empty($fields)) {
            $fields = ['text as content'];
        }
        return model(NoteModel::class)->where([
            'module_id' => module_by_code('global_notice')['id'],
            'link_id' => $globalNoticeId,
            'demand_type' => 'default',
        ])
            ->field($fields)
            ->find();
    }

    /**
     * 查询公告评论
     * @param int $noticeId
     * @param     $page
     * @return array
     */
    public function noticeComments(int $noticeId, $page)
    {
        $globalCommentField = [
            "note.id",
            "note.text AS comment_content",
            "note.created AS comment_time",
            "note.created_by AS comment_user_id",
            "note.comment_subject_id AS comment_pid",
            "user.name AS comment_user_name",
            "user.union_id AS comment_user_union_id",
            "user.avatar AS comment_user_avatar"
        ];

        // 查询对应的评论
        $noticeCommentQuery = model(NoteModel::class)
            ->join("user ON user.id = note.created_by", "LEFT")
            ->field($globalCommentField)
            ->where([
                "note.module_id" => module_by_code('global_notice')['id'],
                "note.link_id" => $noticeId,
                "note.demand_type" => "comment",
                "note.type" => "text",
            ])
            ->order("note.id DESC");
        if ($page) {
            $noticeCommentQuery = $noticeCommentQuery->page(...$page);
        }
        $globalNoticeComments = $noticeCommentQuery->select();

        $globalNoticeComments = $globalNoticeComments ?: [];

        $res = [];
        // 评论只做单子层处理
        foreach ($globalNoticeComments as $comment) {
            if (empty($comment['comment_pid'])) {
                $comment['sub_comments'] = [];
                $res[$comment['id']] = $comment;
            }
        }
        foreach ($globalNoticeComments as $comment) {
            if (!empty($comment['comment_pid'])) {
                if (!isset($res[$comment['comment_pid']]['sub_comments'])) {
                    $res[$comment['comment_pid']]['sub_comments'] = [];
                }
                $res[$comment['comment_pid']]['sub_comments'][] = $comment;
            }
        }
        return array_values($res);
    }

    /**
     * 解析公告筛选类型条件 1:全部公告 2:我发布的公告 3:评论中提到我的公告 4:我评论的公告 5:公告中提到我的
     * @param $filter
     * @param $userId
     * @return array|mixed
     */
    private function parseSearchTypeCondition($filter, $userId)
    {
        $searchType = intval($filter['global_notice.search_type']);
        unset($filter['global_notice.search_type']);
        switch ($searchType) {
            case 1:
                // 全部公告
//                if (!empty($filter)) {
//                    $filter = [$filter];
//                } else {
//                    $filter = [];
//                }
//                $otherFilter = [
//                    "global_notice.created_by" => $userId,
//                    "comment_users.id" => ['EXP', 'is not null'],
//                    "comment.id" => ['EXP', 'is not null'],
//                    "mentioned_users.id" => ['EXP', 'is not null'],
//                    '_logic' => 'OR'
//                ];
//                array_push($filter, $otherFilter);
                break;
            case 2:
                // 我发布的公告
                $filter['global_notice.created_by'] = $userId;
                break;
            case 3:
                // 评论中提到我的公告
                $filter['message_task_confirm.confirm_user_id'] = $userId;
                $filter["message_task_confirm.confirm"] = "default";
                $filter["message_task_confirm.source_type"] = MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_AT;
                break;
            case 4:
                // 我评论的公告
//                $filter['comment.id'] = ['EXP', 'is not null'];
                break;
            case 5:
                // 公告中提到我的
//                $filter['mentioned_users.id'] = ['EXP', 'is not null'];
                break;
            case 6:
                // 待我确认的公告
                $filter['message_task_confirm.confirm_user_id'] = $userId;
                $filter["message_task_confirm.confirm"] = "default";
                $filter["message_task_confirm.source_type"] = MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM;
                break;
            case 7:
                // 与我相关需要确认的公告
                $filter['message_task_confirm.confirm_user_id'] = $userId;
                $filter["message_task_confirm.confirm"] = "default";
                break;
        }

        return $filter;
    }

    /**
     * 确认公告
     * @param $noticeId
     * @param $userId
     * @return array
     * @throw \Exception|\Throwable
     */
    public function confirm($noticeId, $userId)
    {
        return $this->saveUserConfirmStatus($noticeId, $userId, MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM);
    }

    /**
     * 废除公告
     * @param $noticeId
     * @param $userId
     * @return boolean|array
     * @throw \Exception|\Throwable
     */
    public function abolish($noticeId, $userId)
    {
        if (empty($noticeId)) {
            throw new LogicException('invalid notice id', ErrorCode::REQUEST_PARAM_ERROR);
        }
        $globalNoticeModel = model(GlobalNoticeModel::class);
        $noteModel = model(NoteModel::class);
        // 查询公告
        $noticeData = $globalNoticeModel->find($noticeId);
        if (empty($noticeData) || $noticeData['created_by'] != (int)$userId) {
            throw new LogicException('invalid notice id', ErrorCode::REQUEST_PARAM_ERROR);
        }
        $globalNoticeModel->startTrans();
        try {
            $globalNoticeModel->where(['id' => $noticeData['id']])->delete();
            // 删除公告的正文及评论
            $noteModel->where([
                'type' => 'text',
                'module_id' => module_by_code('global_notice')['id'],
                'link_id' => $noticeId
            ])->delete();
            // 删除公告关联的提到的用户以及评论提到的用户
            model(MessageTaskConfirmModel::class)->where([
                'link_id' => $noticeId,
                'link_module_code' => 'global_notice',
            ])->delete();
            $globalNoticeModel->commit();
        } catch (\Throwable $e) {
            $globalNoticeModel->rollback();
            trace("abolish global notice failed:" . $e->getMessage() . PHP_EOL . $e->getTraceAsString() . PHP_EOL, 'ERR');
            throw $e;
        }

        return [];
    }

    /**
     * 查看全局公告详情
     * @param $noticeId
     * @param $userId
     * @return array
     */
    public function view($noticeId, $userId)
    {
        // 查询公告中提到的用户列表
        $globalNoticeField = [
            "global_notice.id",
            "global_notice.type",
            "global_notice.created_by as publisher",
            "global_notice.created as created_at",
            "global_notice.is_top",
            "global_notice.title",
            "user.name AS publisher_name",
            "user.avatar AS publisher_avatar"
        ];
        $noticeData = model(GlobalNoticeModel::class)
            ->field($globalNoticeField)
            ->join("user ON user.id=global_notice.created_by", "LEFT")
            ->where(['global_notice.id' => $noticeId])
            ->find();
        if (empty($noticeData)) {
            throw new LogicException('invalid notice id', ErrorCode::REQUEST_PARAM_ERROR);
        }

        // 查询评论
        $commentCount = model(NoteModel::class)
            ->where([
                'link_id' => $noticeId,
                'module_id' => module_by_code('global_notice')['id'],
                'demand_type' => 'comment',
            ])
            ->count();

        // 查询确认
        $joinList = model(MessageTaskConfirmModel::class)
            ->where([
                'link_id' => $noticeId,
                'link_module_code' => 'global_notice',
                'source_type' => ['in', MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM],
            ])
            ->select();

        $confirmList = [];
        $notConfirmList = [];
        foreach ($joinList as $item) {
            if ($item['confirm'] == 'default') {
                $notConfirmList[$item['confirm_user_id']] = $item['confirm_user_id'];
            } else {
                $confirmList[$item['confirm_user_id']] = $item['confirm_user_id'];
            }
        }

        $noticeData['global_notice_join_count'] = count($joinList);
        $noticeData['global_notice_confirm_count'] = count($confirmList);
        $noticeData['global_notice_reply_count'] = $commentCount;
        $noticeData['is_confirmed'] = in_array($userId, $confirmList);
        $noticeData['need_confirm'] = in_array($userId, $notConfirmList);

        $returnData = $noticeData;

        // 最后设置下评论中提到当前用户的数据为已确认
        $this->saveUserConfirmStatus($noticeId, $userId, MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_AT);
        return $returnData;
    }

    /**
     * 查询最近公告中提到的用户列表
     * @param $param
     * @param $userId
     * @return array
     */
    public function recentMentionedUser($param, $userId)
    {
        $page = isset($param['show_size']) && $param['show_size'] ? [1, intval($param['show_size'])] : [1, 1000];
        $noticeMentionedUserModel = model(NoteModel::class);
        $userModuleId = (int)module_by_code('user')['id'];

        $mentionedUserFields = [
            "user.id AS user_id", "user.name AS user_name", "user.avatar AS user_avatar", "user.union_id AS user_union_id"
        ];

        $mentionedUserList = $noticeMentionedUserModel
            ->alias("mentioned_user")
            ->field($mentionedUserFields)
            ->join("global_notice ON mentioned_user.json->>'$.notice_id'=global_notice.id", "LEFT")
            ->join("user ON mentioned_user.link_id=user.id", "LEFT")
            ->where([
                'mentioned_user.module_id' => $userModuleId,
                "mentioned_user.json->>'$.link_data_type'" => 1,
                "mentioned_user.type" => 'text',
                'global_notice.publisher' => $userId
            ])->group("user.id")
            ->order("mentioned_user.id DESC")
            ->page($page[0], $page[1])
            ->select();

        return $mentionedUserList;
    }

    /**
     * 公告类型筛选列表
     * @return array
     */
    public function noticeTypeOptionData()
    {
        $optionData = OptionsService::getInstance()->getOptionsData('global_notice_type_option');
        $optionData = $optionData ?: [];

        return $optionData;
    }

    /**
     * 公告待确认新通知的提醒
     * @param $userId
     * @return array
     */
    public function notify($userId)
    {
        $globalNoticeModel = model(GlobalNoticeModel::class);
        $userModuleId = (int)module_by_code('user')['id'];

        $unconfirmedNoticeCount = $globalNoticeModel->join("note AS mention_user ON mention_user.json->>'$.notice_id' = global_notice.id AND mention_user.module_id={$userModuleId} AND mention_user.type='text'", "LEFT")
            ->where([
                "mention_user.json->>'$.link_data_type'" => 1,
                "mention_user.json->>'$.is_confirm'" => 0,
                "mention_user.link_id" => $userId
            ])->count();

        $newCommentMentionCount = $globalNoticeModel
            ->join("note AS comment_mention_user ON comment_mention_user.json->>'$.notice_id' = global_notice.id AND comment_mention_user.module_id={$userModuleId} AND comment_mention_user.type='text'", "LEFT")
            ->where([
                "comment_mention_user.json->>'$.link_data_type'" => 2,
                "comment_mention_user.json->>'$.is_confirm'" => 0,
                "comment_mention_user.link_id" => $userId
            ])
            ->group("global_notice.id")
            ->count();

        return [
            'unconfirmed_count' => $unconfirmedNoticeCount ?: 0,
            'new_comment_count' => $newCommentMentionCount ?: 0
        ];
    }

    /**
     * 删除公告评论
     * @param int $noticeId
     * @param int $commentId
     * @param int $userId
     * @return array
     * @throw \Exception|\Throwable
     */
    public function delComment($noticeId, $commentId, $userId)
    {
        $noticeData = model(GlobalNoticeModel::class)->find($noticeId);

        if (empty($noticeData)) {
            throw new LogicException('notice not exists', ErrorCode::REQUEST_PARAM_ERROR);
        }

        $commentData = model(NoteModel::class)
            ->where([
                "id" => $commentId,
                "note.module_id" => module_by_code('global_notice')['id'],
                "note.link_id" => $noticeId,
                "note.demand_type" => "comment",
                "note.type" => "text"
            ])->find();

        if (empty($commentData)) {
            throw new LogicException('notice comment not exists', ErrorCode::REQUEST_PARAM_ERROR);
        }

        model(GlobalNoticeModel::class)->startTrans();

        try {
            $delIds = [$commentData['id']];
            $childCommentRes = model(NoteModel::class)->field('id')->where([
                "note.module_id" => module_by_code('global_notice')['id'],
                "note.link_id" => $noticeId,
                "note.demand_type" => "comment",
                "note.type" => "text",
                'comment_subject_id' => $commentData['id'],
            ])->select();
            if (!empty($childCommentRes)) {
                $delIds = array_merge($delIds, array_column($childCommentRes, 'id'));
            }
            // todo 删除评论中提到的关联用户
            // 删除评论
            model(NoteModel::class)->where([
                'id' => ['in', $delIds]
            ])->delete();
            model(GlobalNoticeModel::class)->commit();
        } catch (\Throwable $e) {
            model(GlobalNoticeModel::class)->rollback();
            APP_DEBUG && trace(format_exception_info($e), 'ERR');
            throw new LogicException('delete notice comment system error', ErrorCode::DELETE_NOTICE_COMMENT_SYSTEM_FAILED);
        }

        return [];
    }

    /***
     * 公告中提到的人员列表
     * @return array
     */
    public function noticeMentionUsers($noticeId, $isConfirmed, $page)
    {
        return model(MessageTaskConfirmModel::class)
            ->join('user on user.id = message_task_confirm.confirm_user_id')
            ->where([
                'message_task_confirm.link_id' => $noticeId,
                'message_task_confirm.link_module_code' => 'global_notice',
                'message_task_confirm.source_type' => MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM,
                'message_task_confirm.confirm' => $isConfirmed == 1 ? "yes" : "default",
            ])
            ->field('message_task_confirm.confirm, user.id as user_id, user.union_id as user_union_id, user.name as user_name, user.avatar')
            ->page(...$page)
            ->select();
    }

    /**
     * 公告附件列表
     * @return array
     */
    public function noticeMediaList($noticeId)
    {
        $res = [];
        $json = self::getContent($noticeId, ['json']);
        $json = json_decode($json['json'], true);
        $mediaString = $json['note_cos_media'] ?? '';
        $globalNoticeMediaIds = explode(',', $mediaString);
        if (!empty($globalNoticeMediaIds)) {
            $globalNoticeMediaList = model(CosMediaModel::class)->where(['id' => ['IN', $globalNoticeMediaIds]])->select();
            foreach ($globalNoticeMediaList as $item) {
                $item['param'] = json_decode($item['param'], true);
                $res[] = $item;
            }
        }
        return $res;
    }

    /**
     * 获取用户确认状态
     * @param $noticeId
     * @param $userId
     * @param $confirmType
     * @return array|false|mixed|string|null
     */
    public function getUserConfirmStatus($noticeId, $userId, $confirmType = MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM)
    {
        return model(MessageTaskConfirmModel::class)
            ->where([
                'link_id' => $noticeId,
                'link_module_code' => 'global_notice',
                'source_type' => $confirmType,
                'confirm_user_id' => $userId
            ])
            ->find();
    }

    /**
     * 更新用户确认状态
     * @param $noticeId
     * @param $userId
     * @param $confirmType
     * @return true
     * @throws \Exception
     */
    public function saveUserConfirmStatus($noticeId, $userId, $confirmType = MessageTaskConfirmModel::SOURCE_TYPE_GLOBAL_NOTICE_CONFIRM)
    {
        $confirmStatus = $this->getUserConfirmStatus($noticeId, $userId, $confirmType);
        if (!empty($confirmStatus) && $confirmStatus['confirm'] = 'default') {
            model(MessageTaskConfirmModel::class)
                ->where(['id' => $confirmStatus['id']])
                ->save(['confirm' => "yes"]);
        }
        return true;
    }
}
